package com.it.machine.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.it.machine.mapper.ActivationCodeMapper;
import com.it.machine.domain.ActivationCode;
import com.it.machine.service.IActivationCodeService;

/**
 * 激活码Service业务层处理
 * 
 * @author 云淡风轻
 * @date 2025-05-08
 */
@Service
public class ActivationCodeServiceImpl implements IActivationCodeService 
{
    // 永久类型常量
    private static final String PERMANENT_TYPE = "PERMANENT";
    
    @Autowired
    private ActivationCodeMapper activationCodeMapper;

    /**
     * 查询激活码
     * 
     * @param id 激活码主键
     * @return 激活码
     */
    @Override
    public ActivationCode selectActivationCodeById(Long id)
    {
        return activationCodeMapper.selectActivationCodeById(id);
    }

    /**
     * 根据激活码查询
     * 
     * @param activeCode 激活码
     * @return 激活码
     */
    @Override
    public ActivationCode selectActivationCodeByCode(String activeCode)
    {
        return activationCodeMapper.selectActivationCodeByCode(activeCode);
    }

    /**
     * 查询激活码列表
     * 
     * @param activationCode 激活码
     * @return 激活码
     */
    @Override
    public List<ActivationCode> selectActivationCodeList(ActivationCode activationCode)
    {
        return activationCodeMapper.selectActivationCodeList(activationCode);
    }

    /**
     * 新增激活码
     * 
     * @param activationCode 激活码
     * @return 结果
     */
    @Override
    public int insertActivationCode(ActivationCode activationCode)
    {
        return activationCodeMapper.insertActivationCode(activationCode);
    }

    /**
     * 修改激活码
     * 
     * @param activationCode 激活码
     * @return 结果
     */
    @Override
    public int updateActivationCode(ActivationCode activationCode)
    {
        return activationCodeMapper.updateActivationCode(activationCode);
    }

    /**
     * 批量删除激活码
     * 
     * @param ids 需要删除的激活码主键
     * @return 结果
     */
    @Override
    public int deleteActivationCodeByIds(Long[] ids)
    {
        return activationCodeMapper.deleteActivationCodeByIds(ids);
    }

    /**
     * 删除激活码信息
     * 
     * @param id 激活码主键
     * @return 结果
     */
    @Override
    public int deleteActivationCodeById(Long id)
    {
        return activationCodeMapper.deleteActivationCodeById(id);
    }

    /**
     * 生成激活码
     * 
     * @param count 需要生成的激活码数量
     * @param proId 项目ID
     * @param proName 项目名称
     * @param mark 积分
     * @param validityType 有效期类型
     * @param validityValue 有效期值
     * @return 生成的激活码列表
     */
    @Override
    public List<ActivationCode> generateActivationCodes(int count, String proId, String proName, Long mark, String validityType, Long validityValue)
    {
        List<ActivationCode> activationList = new ArrayList<>();
        Date now = new Date();
        
        for (int i = 0; i < count; i++) {
            ActivationCode activation = new ActivationCode();
            activation.setProId(proId);
            activation.setProName(proName);
            activation.setActiveCode(generateCode());
            activation.setMark(mark);
            activation.setValidityType(validityType);
            activation.setValidityValue(validityValue);
            activation.setStatus(0L); // 0表示未使用状态
            activation.setAllocateUserId(null); // 初始为未分配
            activation.setAllocateUserName(null);
            activation.setCreateTime(now);
            
            activationCodeMapper.insertActivationCode(activation);
            activationList.add(activation);
        }
        
        return activationList;
    }

    /**
     * 生成唯一激活码
     */
    private String generateCode()
    {
        return UUID.randomUUID().toString().toUpperCase();
    }

    /**
     * 验证激活码是否有效
     * 
     * @param proId 项目ID
     * @param activeCode 激活码
     * @return 验证结果：0-有效，1-无效，2-已使用，4-已过期
     */
    @Override
    public int validateActivationCode(String proId, String activeCode)
    {
        ActivationCode code = activationCodeMapper.selectActivationCodeByCode(activeCode);
        if (code == null || !code.getProId().equals(proId))
        {
            return 1; // 无效激活码
        }
        
        if (code.getStatus() == 1L)
        {
            return 2; // 已使用
        }
        
        // 检查是否过期
        if (code.getValidityType() != null && !PERMANENT_TYPE.equals(code.getValidityType()))
        {
            // 对于非永久类型，检查有效期值是否存在
            if (code.getValidityValue() != null)
            {
                Calendar cal = Calendar.getInstance();
                cal.setTime(code.getCreateTime());
                
                if ("day".equals(code.getValidityType()))
                {
                    cal.add(Calendar.DAY_OF_MONTH, code.getValidityValue().intValue());
                }
                else if ("month".equals(code.getValidityType()))
                {
                    cal.add(Calendar.MONTH, code.getValidityValue().intValue());
                }
                else if ("year".equals(code.getValidityType()))
                {
                    cal.add(Calendar.YEAR, code.getValidityValue().intValue());
                }
                
                if (cal.getTime().before(new Date()))
                {
                    return 4; // 已过期
                }
            }
        }
        
        return 0; // 有效
    }
    
    /**
     * 根据用户ID查询激活码列表
     * 
     * @param allocateUserId 分配用户ID
     * @return 激活码集合
     */
    @Override
    public List<ActivationCode> selectActivationCodesByAllocateUserId(Long allocateUserId)
    {
        ActivationCode activationCode = new ActivationCode();
        activationCode.setAllocateUserId(allocateUserId);
        return activationCodeMapper.selectActivationCodeList(activationCode);
    }
    
    /**
     * 根据项目ID查询未分配的激活码
     * 
     * @param proId 项目ID
     * @return 激活码集合
     */
    @Override
    public List<ActivationCode> selectUnallocatedActivationCodesByProId(String proId)
    {
        ActivationCode activationCode = new ActivationCode();
        activationCode.setProId(proId);
        activationCode.setAllocateUserId(null); // 未分配
        activationCode.setStatus(0L); // 未使用
        return activationCodeMapper.selectActivationCodeList(activationCode);
    }
    
    /**
     * 分配激活码给用户
     * 
     * @param ids 激活码ID集合
     * @param allocateUserId 分配用户ID
     * @param allocateUserName 分配用户名
     * @return 结果
     */
    @Override
    public int allocateActivationCodesToUser(Long[] ids, Long allocateUserId, String allocateUserName)
    {
        if (ids == null || ids.length == 0)
        {
            return 0;
        }
        
        // 直接调用XML中已定义的allocateActivationCodesToUser方法
        return activationCodeMapper.allocateActivationCodesToUser(ids, allocateUserId, allocateUserName, new Date());
    }
    
    /**
     * 批量分配激活码给用户
     * 
     * @param proId 项目ID
     * @param count 分配数量
     * @param allocateUserId 分配用户ID
     * @param allocateUserName 分配用户名
     * @return 分配的激活码列表
     */
    @Override
    public List<ActivationCode> batchAllocateActivationCodes(String proId, int count, Long allocateUserId, String allocateUserName)
    {
        // 首先查询未分配的激活码
        // 获取所有未分配的激活码
        List<ActivationCode> allUnallocatedCodes = selectUnallocatedActivationCodesByProId(proId);
        // 根据需要截取指定数量的激活码
        List<ActivationCode> unallocatedCodes = allUnallocatedCodes.stream()
                .limit(count)
                .collect(java.util.stream.Collectors.toList());
        
        if (unallocatedCodes == null || unallocatedCodes.isEmpty())
        {
            return new ArrayList<>();
        }
        
        // 提取激活码ID
        Long[] ids = new Long[unallocatedCodes.size()];
        for (int i = 0; i < unallocatedCodes.size(); i++)
        {
            ids[i] = unallocatedCodes.get(i).getId();
        }
        
        // 分配激活码
        allocateActivationCodesToUser(ids, allocateUserId, allocateUserName);
        
        // 更新返回列表中的分配信息
        for (ActivationCode code : unallocatedCodes)
        {
            code.setAllocateUserId(allocateUserId);
            code.setAllocateUserName(allocateUserName);
            code.setUpdateTime(new Date());
        }
        
        return unallocatedCodes;
    }
}